package com.iot.iotplus.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.iot.iotplus.accept.MqttAcceptClient;
import com.iot.iotplus.base.Result;
import com.iot.iotplus.base.ResultCode;
import com.iot.iotplus.base.vo.DirectiveVO;
import com.iot.iotplus.entity.Device;
import com.iot.iotplus.entity.Product;
import com.iot.iotplus.entity.Tenant;
import com.iot.iotplus.mapper.DeviceMapper;
import com.iot.iotplus.mapper.MqttUserMapper;
import com.iot.iotplus.mapper.ProductMapper;
import com.iot.iotplus.mapper.TenantMapper;
import com.iot.iotplus.mqtt.SendClient;
import com.iot.iotplus.service.AuthenticationService;
import com.iot.iotplus.utils.ResultUtil;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class AuthenticationServiceImpl implements AuthenticationService {
    @Autowired
    private ProductMapper productMapper;//产品mapper
    @Autowired
    private DeviceMapper deviceMapper;//设备mapper
    @Autowired
    private MqttUserMapper mqttUserMapper;//mqtt用户mapper
    @Autowired
    private MqttAcceptClient mqttAcceptClient;
    @Autowired
    private SendClient sendClient;
    @Autowired
    private TenantMapper tenantMapper;
    @Override
    public Result<?> checkAuth(String productKey, String deviceKey, String deviceSecret) {
        try{
            Optional.of(productKey);
            Optional.of(deviceKey);
            Optional.of(deviceSecret);
        }catch (NullPointerException e){
            return new Result<>(ResultCode.VALIDATE_FAILED.getCode(), ResultCode.VALIDATE_FAILED.getMessage(), null);
        }
        LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(Product::getProductKey, productKey);
        Product product = productMapper.selectOne(productWrapper);
        if (product == null)
            return new Result<>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMessage(), null);

        LambdaQueryWrapper<Device> deviceWrapper = new LambdaQueryWrapper<>();
        deviceWrapper.eq(Device::getDeviceKey, deviceKey);
        deviceWrapper.eq(Device::getProductId, product.getId());
        deviceWrapper.eq(Device::getDeviceSecret, deviceSecret);
        Device device = deviceMapper.selectOne(deviceWrapper);
        if (device == null)
            return new Result<>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMessage(), null);
        String tenantId = device.getTenantId();
        mqttAcceptClient.connect(tenantId);
        mqttAcceptClient.subscribe(deviceKey,0);
        String userName = mqttUserMapper.selectByTenantIdMqttUserName(device.getTenantId());

        return new Result<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), userName);
    }

    @Override
    public Result<?> publish(String accessKey, String accessSecurity, String sign, DirectiveVO directive) {
        LambdaQueryWrapper<Tenant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tenant::getAccessKey,accessKey);
        wrapper.eq(Tenant::getAccessSecurity,accessSecurity);
        Tenant tenant = tenantMapper.selectOne(wrapper);
        if (tenant == null)
            return ResultUtil.failed();
        String message = JSON.toJSONString(directive);
//        mqttAcceptClient.publish(0,false,directive.getDeviceKey(),message);
        String topic = "smart/device/ctrl/"+tenant.getId();
        MqttClient client = sendClient.connect(tenant.getId());
        sendClient.publish(client,1,topic,message);
        return ResultUtil.success(null);
    }

}
